import SparkMD5 from 'spark-md5';
import WebUploader from 'webuploader';


// 上传每个分片的大小
const CHUNK_SIZE = 1024 << 10;
const BLOB_SLICE = File.prototype.slice;
WebUploader.Uploader.register({
    'before-send-file': 'beforeSendFile', //整个文件上传前
    'before-send': 'beforeSend' //每个分片上传前
  },
  {
    beforeSend: function (block) {
      // console.log('beforeSend block -->', block);
      let doneChunkPartIndex = block.file.source.source.currentChunk;//获取已经上传过的下标
      let deferred = WebUploader.Deferred();
      // console.log('doneChunkPartIndex -->', doneChunkPartIndex)
      if (doneChunkPartIndex > 0) {
        if (block.chunk > doneChunkPartIndex) {
          //分块不存在，重新发送该分块内容
          deferred.resolve();
        } else {
          //分块存在，跳过
          // console.log('分块存在，跳过');
          deferred.reject();
        }
      } else {
        //分块不存在，重新发送该分块内容
        deferred.resolve();
      }
      return deferred.promise();
    },
  });

/** uploader 配置 */
export interface UploaderConfig {
  // 服务器上传地址
  server: string
  // 上传分片大小
  chunkSize: number
  // 上传重试次数
  chunkRetry?: number
  // 上传并发数
  threads?: number
  // 多文件上传
  multiple?: boolean
  // 上传结束回调函数
  uploadFinishedFunction?: () => void
  // 上传文件校验状态函数
  uploadAcceptFunction?: (object, ret) => void
  // 上传文件成功回调函数
  uploadSuccessFunction?: (file, response) => void
  // 上传文件错误回调函数
  uploadErrorFunction?: (file, response) => void
  // 上传文件最终回调函数
  uploadCompleteFunction?: (file, response) => void
  // 上传文件进度回调函数
  uploadProgressFunction?: (file, percentage) => void
  // 发送请求前回调函数
  uploadBeforeSend?: (obj, data, headers) => void
}

/** 初始化 uploader */
export function initUploader(config: UploaderConfig) {
  let defaultConfig: UploaderConfig = {
    server: config.server,
    chunkSize: config.chunkSize,
    chunkRetry: config.chunkRetry ? config.chunkRetry : 3,
    threads: config.threads ? config.threads : 5,
    multiple: config.multiple === undefined || config.multiple == null ? false : config.multiple
  }
  const uploader = WebUploader.create({
    auto: false,//是否自动上传，true为自动上传
    method: 'post',
    server: defaultConfig.server,
    chunked: true,
    chunkSize: defaultConfig.chunkSize,
    chunkRetry: defaultConfig.chunkRetry,//网络问题上传失败后重试次数
    threads: defaultConfig.threads, //上传并发数
    multiple: defaultConfig.multiple,
    resize: false
  });
  uploader.on('uploadFinished', function () {
    //清空队列
    // console.log('finish')
    uploader.reset();
    if (config.uploadFinishedFunction) {
      config.uploadFinishedFunction();
    }
  });
  uploader.on('uploadAccept', function (object, ret) {
    // console.log('uploadAccept obj -->', object);
    // console.log('uploadAccept ret -->', ret);
    if (config.uploadAcceptFunction) {
      config.uploadAcceptFunction(object, ret);
    }
    return ret.code === 0;
  })
  uploader.on('uploadSuccess', function (file, response) {
    // console.log('response -->', response);
    // console.log('file -->', file);
    if (config.uploadSuccessFunction) {
      config.uploadSuccessFunction(file, response);
    }
    // if (!response || response.code === 0) {
    // 	for (let valueElement of renderFileList.value) {
    // 		if (file.source.source.md5 === valueElement.md5) {
    // 			message.success('上传校验成功')
    // 			valueElement.percentage = 100;
    // 		}
    // 	}
    // }
    uploader.removeFile(file);
  });
  uploader.on('uploadError', function (file, response) {
    uploader.reset();
    if (config.uploadErrorFunction) {
      config.uploadErrorFunction(file, response);
    }
    // if (tempFileList.value.length > 0) {
    // 	uploader.addFiles(tempFileList.value);
    // }
    // renderFileList.value = renderFileList.value.map(file => {
    // 	file.percentage = 0;
    // 	return file;
    // });
    // message.error('上传失败请重试');
  });
  uploader.on('uploadComplete', function (file, response) {
    if (config.uploadCompleteFunction) {
      config.uploadCompleteFunction(file, response);
    }
  });
  // 文件上传过程中创建进度条实时显示。
  uploader.on('uploadProgress', function (file, percentage) {
    if (config.uploadProgressFunction) {
      config.uploadProgressFunction(file, percentage);
    }
    // for (let valueElement of renderFileList.value) {
    // 	if (file.md5 === valueElement.md5) {
    // 		if (percentage >= (valueElement.percentage) / 100) {
    // 			valueElement.percentage = percentage * 100;
    // 		}
    // 	}
    // }
  });
  uploader.on('uploadBeforeSend', function (obj, data, headers) {
    if (config.uploadBeforeSend) {
      config.uploadBeforeSend(obj, data, headers);
    }
  });
  return uploader;
}

/** 分片计算文件 md5 */
export function mathMd5(file: any, fn: (md5: any, file: any) => void, preFn?: (file: any) => void) {
  /** 对下一次分片进行 md5 计算 */
  function next(fileReader, currentChunk, fileSize, f) {
    let start = currentChunk * 1024 << 10,
      end = (start + CHUNK_SIZE) >= fileSize ? fileSize : start + CHUNK_SIZE;
    fileReader.readAsArrayBuffer(BLOB_SLICE.call(f, start, end));
  }

  let md5 = '';
  let f = file,
    fileSize = f.size,
    fileReader = new FileReader(),
    chunks = Math.ceil(fileSize / CHUNK_SIZE),
    currentChunk = 0,
    spark = new SparkMD5.ArrayBuffer();
  if (preFn) {
    preFn(f);
  }
  fileReader.onload = function (e) {
    if (e.target) {
      spark.append(e.target.result);
    }

    currentChunk++;
    if (currentChunk < chunks) {
      next(fileReader, currentChunk, fileSize, f);
    } else {
      md5 = spark.end(false);
      // file.md5 = md5;
      // f.md5 = md5;
      // 计算完 MD5 可以设置后置函数
      if (fn) {
        fn(md5, f);
      }
    }
  }
  next(fileReader, currentChunk, fileSize, f);
}